/*
* @Author: baidwwy
* @Date:   2020-01-28 23:55:19
* @Last Modified by:   baidwwy
* @Last Modified time: 2020-10-29 23:26:40
*/

#include "help.h"

// Windows
static int Begin(lua_State* L){//
	bool r = false;
	if(lua_istable(L,2)){
		bool v;
		getbyref(L,2,v);
		r = ImGui::Begin(luaL_checkstring(L,1),&v,luaL_optint(L,3,ImGuiWindowFlags_NoSavedSettings));
		setbyref(L,2,v);
	}else{
		r = ImGui::Begin(luaL_checkstring(L,1),NULL,luaL_optint(L,2,ImGuiWindowFlags_NoSavedSettings));
	}
    lua_pushboolean(L,r);
    return 1;
}

static int End(lua_State* L){//
    ImGui::End();
    return 0;
}
//==========================================================================
// Child Windows
static int BeginChild(lua_State* L){//
    ImVec2 size(0,0);
	getImVec2(L,2,size);
	bool r;
	if (lua_isinteger(L,1)){
		ImGuiID id = (ImGuiID)luaL_checkint(L,1);
		r = ImGui::BeginChild(id,size,luaL_optboolean(L,4,false),luaL_optint(L,5,0));
	}else
		r = ImGui::BeginChild(luaL_checkstring(L,1),size,luaL_optboolean(L,4,false),luaL_optint(L,5,0));
    lua_pushboolean(L,r);
    return 1;
}

static int EndChild(lua_State* L){//
    ImGui::EndChild();
    return 0;
}
//==========================================================================
// Windows Utilities

static int IsWindowAppearing(lua_State* L){//
	lua_pushboolean(L,ImGui::IsWindowAppearing());
    return 1;
}

static int IsWindowCollapsed(lua_State* L){//
	lua_pushboolean(L,ImGui::IsWindowCollapsed());
	return 1;
}

static int IsWindowFocused(lua_State* L){//
	lua_pushboolean(L,ImGui::IsWindowFocused(luaL_optint(L,1,0)));
	return 1;
}

static int IsWindowHovered(lua_State* L){//
	lua_pushboolean(L,ImGui::IsWindowHovered(luaL_optint(L,1,0)));
	return 1;
}
//TODO
static int GetWindowDrawList(lua_State* L){
	//ImGui::GetWindowDrawList();
    return 0;
}

static int GetWindowPos(lua_State* L){//
	ImVec2 v = ImGui::GetWindowPos();
	pushImVec2(L,v);
    return 2;
}

static int GetWindowSize(lua_State* L){//
	ImVec2 v = ImGui::GetWindowSize();
	pushImVec2(L,v);
	return 2;
}

static int GetWindowWidth(lua_State* L){//
	lua_pushnumber(L,ImGui::GetWindowWidth());
    return 1;
}

static int GetWindowHeight(lua_State* L){//
	lua_pushnumber(L,ImGui::GetWindowHeight());
	return 1;
}
//==========================================================================
// Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin).
static int SetNextWindowPos(lua_State* L){//
	ImVec2 pos(0,0);
	ImVec2 pivot(0,0);
	getImVec2(L,1,pos);
	getImVec2(L,4,pivot);
	ImGui::SetNextWindowPos(pos,luaL_optint(L,3,0) , pivot);//ImGuiCond_Always
    return 0;
}

static int SetNextWindowSize(lua_State* L){//
	ImVec2 size(0,0);
	getImVec2(L,1,size);
	ImGui::SetNextWindowSize(size,luaL_optint(L,3,0));
    return 0;
}

static int SetNextWindowSizeConstraints(lua_State* L){//
	ImVec2 min,max;
	getImVec2(L,1,min);
	getImVec2(L,3,max);
	ImGui::SetNextWindowSizeConstraints(min,max);
    return 0;
}

static int SetNextWindowContentSize(lua_State* L){//
	ImVec2 v(0,0);
	getImVec2(L,1,v);
	ImGui::SetNextWindowContentSize(v);
	return 0;
}

static int SetNextWindowCollapsed(lua_State* L){//
	ImGui::SetNextWindowCollapsed(luaL_checkboolean(L,1),luaL_optint(L,2,0));
    return 0;
}

static int SetNextWindowFocus(lua_State* L){//
	ImGui::SetNextWindowFocus();
    return 0;
}

static int SetNextWindowBgAlpha(lua_State* L){//
	ImGui::SetNextWindowBgAlpha(luaL_checkfloat(L,1));
    return 0;
}

static int SetWindowPos(lua_State* L){//
	ImVec2 v(0,0);
	if (lua_isstring(L,1)){
		getImVec2(L,2,v);
		ImGui::SetWindowPos(luaL_checkstring(L,1),v,luaL_optint(L,4,0));
	}else{
		getImVec2(L,1,v);
		ImGui::SetWindowPos(v,luaL_optint(L,3,0));
	}
    return 0;
}

static int SetWindowSize(lua_State* L){//
	ImVec2 v(0,0);
	if (lua_isstring(L,1)){
		getImVec2(L,2,v);
		ImGui::SetWindowSize(luaL_checkstring(L,1),v,luaL_optint(L,4,0));
	}else{
		getImVec2(L,1,v);
		ImGui::SetWindowSize(v,luaL_optint(L,3,0));
	}

    return 0;
}

static int SetWindowCollapsed(lua_State* L){//
	if (lua_isstring(L,1))
		ImGui::SetWindowCollapsed(luaL_checkstring(L,1),luaL_checkboolean(L,2),luaL_optint(L,3,0));
	else
		ImGui::SetWindowCollapsed(luaL_checkboolean(L,1),luaL_optint(L,2,0));
    return 0;
}

static int SetWindowFocus(lua_State* L){//
	if (lua_isnoneornil(L,1))
		ImGui::SetWindowFocus();
	else
		ImGui::SetWindowFocus(luaL_checkstring(L,1));
    return 0;
}

static int SetWindowFontScale(lua_State* L){//
	ImGui::SetWindowFontScale(luaL_checkfloat(L,1));
    return 0;
}
//==========================================================================
// Content region
static int GetContentRegionAvail(lua_State* L) {//
	ImVec2 v = ImGui::GetContentRegionAvail();
	pushImVec2(L, v);
	return 2;
}

static int GetContentRegionMax(lua_State* L){//
    ImVec2 v = ImGui::GetContentRegionMax();
	pushImVec2(L,v);
    return 2;
}

static int GetWindowContentRegionMin(lua_State* L){//
    ImVec2 v = ImGui::GetWindowContentRegionMin();
	pushImVec2(L,v);
	return 2;
}

static int GetWindowContentRegionMax(lua_State* L){//
    ImVec2 v = ImGui::GetWindowContentRegionMax();
	pushImVec2(L,v);
	return 2;
}

static int GetWindowContentRegionWidth(lua_State* L){//
	lua_pushnumber(L,ImGui::GetWindowContentRegionWidth());
	return 1;
}
//==========================================================================
// Windows Scrolling
static int GetScrollX(lua_State* L){//
    lua_pushnumber(L,ImGui::GetScrollX());
    return 1;
}

static int GetScrollY(lua_State* L){//
	lua_pushnumber(L,ImGui::GetScrollY());
	return 1;
}

static int SetScrollX(lua_State* L) {//
	ImGui::SetScrollX(luaL_checkfloat(L, 1));
	return 0;
}

static int SetScrollY(lua_State* L) {//
	ImGui::SetScrollY(luaL_checkfloat(L, 1));
	return 0;
}

static int GetScrollMaxX(lua_State* L){//
	lua_pushnumber(L,ImGui::GetScrollMaxX());
	return 1;
}

static int GetScrollMaxY(lua_State* L){//
	lua_pushnumber(L,ImGui::GetScrollMaxY());
	return 1;
}

static int SetScrollHereX(lua_State* L){//
    ImGui::SetScrollHereX(luaL_optfloat(L,1,0.5f));
    return 0;
}

static int SetScrollHereY(lua_State* L){//
    ImGui::SetScrollHereY(luaL_optfloat(L,1,0.5f));
    return 0;
}

static int SetScrollFromPosX(lua_State* L){//
    ImGui::SetScrollFromPosX(luaL_optfloat(L,1,0.5f));
    return 0;
}

static int SetScrollFromPosY(lua_State* L){//
    ImGui::SetScrollFromPosY(luaL_optfloat(L,1,0.5f));
    return 0;
}
//==========================================================================
// Parameters stacks (shared)
//TODO
static int PushFont(lua_State* L){
	//ImGui::PushFont(ImFont* font);
    return 0;
}

static int PopFont(lua_State* L){//
	ImGui::PopFont();
    return 0;
}

static int PushStyleColor(lua_State* L){//
	if(lua_istable(L,2)){
		ImVec4 v(0,0,0,0);
		getImVec4(L,2,v);
		ImGui::PushStyleColor(luaL_checkint(L,1), v);
	}else
		ImGui::PushStyleColor(luaL_checkint(L,1), luaL_checkint(L,2));
    return 0;
}

static int PopStyleColor(lua_State* L){//
	ImGui::PopStyleColor(luaL_optint(L,1,1));
    return 0;
}

static int PushStyleVar(lua_State* L){//
	if (lua_istable(L,2)){
		ImVec2 v(0,0);
		getImVec2(L,2,v);
		ImGui::PushStyleVar(luaL_checkint(L,1), v);
	}else
		ImGui::PushStyleVar(luaL_checkint(L,1), luaL_checkfloat(L,2));

    return 0;
}

static int PopStyleVar(lua_State* L){//
	ImGui::PopStyleVar(luaL_optint(L,1,1));
    return 0;
}

static int PushAllowKeyboardFocus(lua_State* L) {//
	ImGui::PushAllowKeyboardFocus(luaL_checkboolean(L, 1));
	return 0;
}

static int PopAllowKeyboardFocus(lua_State* L) {//
	ImGui::PopAllowKeyboardFocus();
	return 0;
}

static int PushButtonRepeat(lua_State* L) {//
	ImGui::PushButtonRepeat(luaL_checkboolean(L, 1));
	return 0;
}

static int PopButtonRepeat(lua_State* L) {//
	ImGui::PopButtonRepeat();
	return 0;
}
//==========================================================================
// Parameters stacks (current window)

static int PushItemWidth(lua_State* L) {//
	ImGui::PushItemWidth(luaL_checkfloat(L, 1));
	return 0;
}

static int PopItemWidth(lua_State* L) {//
	ImGui::PopItemWidth();
	return 0;
}

static int SetNextItemWidth(lua_State* L) {//
	ImGui::SetNextItemWidth(luaL_checkfloat(L, 1));
	return 0;
}

static int CalcItemWidth(lua_State* L) {//
	lua_pushnumber(L, ImGui::CalcItemWidth());
	return 1;
}

static int PushTextWrapPos(lua_State* L) {//
	ImGui::PushTextWrapPos(luaL_checkfloat(L, 1));
	return 0;
}

static int PopTextWrapPos(lua_State* L) {//
	ImGui::PopTextWrapPos();
	return 0;
}
//==========================================================================
// Style read access

//TODO
static int GetFont(lua_State* L){
	//ImGui::GetFont()
    return 0;
}

static int GetFontSize(lua_State* L){//
	lua_pushnumber(L,ImGui::GetFontSize());
    return 1;
}

static int GetFontTexUvWhitePixel(lua_State* L){//
	ImVec2 v = ImGui::GetFontTexUvWhitePixel();
	pushImVec2(L,v);
    return 2;
}

static int GetColorU32(lua_State* L){//
	switch (lua_gettop(L))
	{
	case 1:{
		ImU32 v = luaL_checkint(L,1);
		v = ImGui::GetColorU32(v);
		lua_pushinteger(L,v);
		return 1;};
	case 2:{
		ImU32 v;
		ImGuiCol i = luaL_checkint(L,1);
		float alpha_mul = luaL_checkfloat(L,1);
		v = ImGui::GetColorU32(i,alpha_mul);
		lua_pushinteger(L,v);
		return 1;};
	case 4:{
		ImU32 v;
		ImVec4 c;
		getImVec4(L,1,c);
		v = ImGui::GetColorU32(c);
		lua_pushinteger(L,v);
		return 1;};
	}
	return 0;
}

static int GetStyleColorVec4(lua_State* L) {//
	ImVec4 v = ImGui::GetStyleColorVec4(luaL_checkint(L, 1));
	pushImVec4(L, v);
	return 4;
}

//==========================================================================
// Cursor / Layout
static int Separator(lua_State* L){//
	ImGui::Separator();
	return 0;
}

static int SameLine(lua_State* L){//
	ImGui::SameLine(luaL_optfloat(L,1,0.0f),luaL_optfloat(L,2,-1.0f));
	return 0;
}

static int NewLine(lua_State* L){//
	ImGui::NewLine();
    return 0;
}

static int Spacing(lua_State* L){//
	ImGui::Spacing();
    return 0;
}

static int Dummy(lua_State* L){//
	ImVec2 v(0,0);
	getImVec2(L,1,v);
	ImGui::Dummy(v);
    return 0;
}

static int Indent(lua_State* L){//
	ImGui::Indent(luaL_optfloat(L,1,0.0f));
    return 0;
}
static int Unindent(lua_State* L){//
	ImGui::Unindent(luaL_optfloat(L,1,0.0f));
    return 0;
}

static int BeginGroup(lua_State* L){//
	ImGui::BeginGroup();
    return 0;
}

static int EndGroup(lua_State* L){//
	ImGui::EndGroup();
    return 0;
}

static int GetCursorPos(lua_State* L){//
	ImVec2 v = ImGui::GetCursorPos();
	pushImVec2(L,v);
    return 2;
}

static int GetCursorPosX(lua_State* L){//
	lua_pushnumber(L,ImGui::GetCursorPosX());
    return 1;
}

static int GetCursorPosY(lua_State* L){//
	lua_pushnumber(L,ImGui::GetCursorPosY());
	return 1;
}

static int SetCursorPos(lua_State* L){//
	ImVec2 v(0,0);
	getImVec2(L,1,v);
	ImGui::SetCursorPos(v);
    return 0;
}

static int SetCursorPosX(lua_State* L){//
	ImGui::SetCursorPosX(luaL_checkfloat(L,1));
    return 0;
}

static int SetCursorPosY(lua_State* L){//
	ImGui::SetCursorPosY(luaL_checkfloat(L,1));
    return 0;
}

static int GetCursorStartPos(lua_State* L){//
	ImVec2 v = ImGui::GetCursorStartPos();
	pushImVec2(L,v);
	return 2;
}

static int GetCursorScreenPos(lua_State* L){//
	ImVec2 v = ImGui::GetCursorScreenPos();
	pushImVec2(L,v);
	return 2;
}

static int SetCursorScreenPos(lua_State* L){//
	ImVec2 v(0,0);
	getImVec2(L,1,v);
	ImGui::SetCursorScreenPos(v);
	return 0;
}

static int AlignTextToFramePadding(lua_State* L){//
	ImGui::AlignTextToFramePadding();
    return 0;
}

static int GetTextLineHeight(lua_State* L){//
	lua_pushnumber(L,ImGui::GetTextLineHeight());
	return 1;
}

static int GetTextLineHeightWithSpacing(lua_State* L){//
	lua_pushnumber(L,ImGui::GetTextLineHeightWithSpacing());
	return 1;
}

static int GetFrameHeight(lua_State* L){//
	lua_pushnumber(L,ImGui::GetFrameHeight());
	return 1;
}

static int GetFrameHeightWithSpacing(lua_State* L){//
	lua_pushnumber(L,ImGui::GetFrameHeightWithSpacing());
	return 1;
}
//==========================================================================
// ID stack/scopes
static int PushID(lua_State* L){//
	if (lua_isinteger(L,1)){
		ImGui::PushID(luaL_checkint(L,1));
	}else if (lua_isstring(L,1) && lua_isstring(L,2)){
		ImGui::PushID(lua_tostring(L,1),lua_tostring(L,2));
	}else if (lua_isstring(L,1)){
		ImGui::PushID(lua_tostring(L,1));
	}
	return 0;
}

static int PopID(lua_State* L){//
	ImGui::PopID();
    return 0;
}

static int GetID(lua_State* L){//
	if (lua_isstring(L,1) && lua_isstring(L,2))
		lua_pushinteger(L,ImGui::GetID(lua_tostring(L,1),lua_tostring(L,2)));
	else
		lua_pushinteger(L,ImGui::GetID(luaL_checkstring(L,1)));
    return 1;
}
//==========================================================================
// Widgets: Text
static int TextUnformatted(lua_State* L){//
	ImGui::TextUnformatted(luaL_optstring(L,1,"nil"),luaL_optstring(L,2,NULL));
	return 0;
}

static int Text(lua_State* L){//
	ImGui::Text(luaL_optstring(L,1,"nil"));
    return 0;
}

static int TextColored(lua_State* L){//
	ImVec4 col(1,1,1,1);
	getImVec4(L,2,col);
	ImGui::TextColored(col,luaL_optstring(L,1,"nil"));
    return 0;
}

static int TextDisabled(lua_State* L){//
	ImGui::TextDisabled(luaL_optstring(L,1,"nil"));
    return 0;
}

static int TextWrapped(lua_State* L){//
	ImGui::TextWrapped(luaL_optstring(L,1,"nil"));
    return 0;
}

static int LabelText(lua_State* L){//
	ImGui::LabelText(luaL_checkstring(L,1),luaL_optstring(L,2,"nil"));
    return 0;
}

static int BulletText(lua_State* L){//
	ImGui::BulletText(luaL_optstring(L,1,"nil"));
    return 0;
}
//==========================================================================
// Widgets: Main
static int Button(lua_State* L){//
	ImVec2 v(0,0);
	getImVec2(L,2,v);
	lua_pushboolean(L,ImGui::Button(luaL_checkstring(L,1),v));
    return 1;
}

static int SmallButton(lua_State* L){//
	lua_pushboolean(L,ImGui::SmallButton(luaL_checkstring(L,1)));
    return 1;
}

static int InvisibleButton(lua_State* L){//
	ImVec2 size(0,0);
	getImVec2(L,2,size);
	lua_pushboolean(L,ImGui::InvisibleButton(luaL_checkstring(L,1),size));
    return 1;
}

static int ArrowButton(lua_State* L){//
	bool r = ImGui::ArrowButton(luaL_checkstring(L,1), luaL_optint(L,2,ImGuiDir_None));
	lua_pushboolean(L,r);
    return 1;
}
//TODO
static int Image(lua_State* L){
	float w,h;
	ImTextureID tex = gettexture(L,1,w,h);
	ImVec2 size(w,h);
	gettableVec2(L,2,size);
	ImVec2 uv0(0,0);
	gettableVec2(L,3,uv0);
	ImVec2 uv1(1,1);
	gettableVec2(L,4,uv1);
	ImVec4 co1(1,1,1,1);
	gettableVec4(L,5,co1);
	ImVec4 co2(0,0,0,0);
	gettableVec4(L,6,co2);
	ImGui::Image(tex,size,uv0,uv1,co1,co2);

    return 0;
}

static int ImageButton(lua_State* L){
	float w,h;
	ImTextureID tex = gettexture(L,1,w,h);
	ImVec2 size(w,h);
	gettableVec2(L,2,size);
	ImVec2 uv0(0,0);
	gettableVec2(L,3,uv0);
	ImVec2 uv1(1,1);
	gettableVec2(L,4,uv1);
	ImVec4 co1(1,1,1,1);
	gettableVec4(L,6,co1);
	ImVec4 co2(0,0,0,0);
	gettableVec4(L,7,co2);
	bool r= ImGui::ImageButton(tex,size,uv0,uv1,luaL_optint(L,5,-1),co1,co2);
	lua_pushboolean(L,r);
    return 1;
}

static int Checkbox(lua_State* L){//
	bool v ;
	getbyref(L,2,v);
	bool r = ImGui::Checkbox(luaL_checkstring(L,1), &v);
	setbyref(L,2,v);
	lua_pushboolean(L,r);
    return 1;
}

static int CheckboxFlags(lua_State* L){//
	unsigned int v ;
	getbyref(L,2,v);
	bool r = ImGui::CheckboxFlags(luaL_checkstring(L,1), &v,luaL_checkint(L,3));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
    return 0;
}

static int RadioButton(lua_State* L){//
	bool r;
	if(lua_isboolean(L,2)){
		r = ImGui::RadioButton(luaL_checkstring(L,1), luaL_checkboolean(L,2));
	}else{
		int v;
		getbyref(L,2,v);
		r = ImGui::RadioButton(luaL_checkstring(L,1), &v, luaL_checkint(L,3));
		setbyref(L,2,v);
	}

	lua_pushboolean(L,r);
	return 1;
}

static int ProgressBar(lua_State* L){//
	ImVec2 size(-1,0);
	getImVec2(L,2,size);
	ImGui::ProgressBar(luaL_checkfloat(L,1),size,luaL_optstring(L,4,NULL));
    return 0;
}

static int Bullet(lua_State* L){//
	ImGui::Bullet();
    return 0;
}
//==========================================================================
// Widgets: Combo Box
static int BeginCombo(lua_State* L){//
	bool r = ImGui::BeginCombo(luaL_checkstring(L,1),luaL_checkstring(L,2),luaL_optint(L,3,0));
	lua_pushboolean(L,r);
    return 1;
}

static int EndCombo(lua_State* L){//
	ImGui::EndCombo();
    return 0;
}

static int Combo(lua_State* L){
	int n ;
	bool r;
	getbyref(L,2,n);--n;
	if(lua_istable(L,3)){
		tabledata data(L,3);
		r = ImGui::Combo(luaL_checkstring(L,1), &n, items_getter,&data,(int)luaL_len(L,3),luaL_optint(L,4,-1));
	}else
		r = ImGui::Combo(luaL_checkstring(L,1), &n, luaL_checklstring(L,3,NULL),luaL_optint(L,4,-1));
	setbyref(L,2,++n);
	lua_pushboolean(L,r);
    return 1;
}
//==========================================================================
// Widgets: Drags
static int DragFloat(lua_State* L){
	float v;
	getbyref(L,2,v);
	bool r = ImGui::DragFloat(luaL_checkstring(L,1), &v, luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optfloat(L,5,0.0f),luaL_optstring(L,6,"%.3f"),luaL_optfloat(L,7,1.0f));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragFloat2(lua_State* L){
	float v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::DragFloat2(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optfloat(L,5,0.0f),luaL_optstring(L,6,"%.3f"),luaL_optfloat(L,7,1.0f));
    setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragFloat3(lua_State* L){
	float v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::DragFloat3(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optfloat(L,5,0.0f),luaL_optstring(L,6,"%.3f"),luaL_optfloat(L,7,1.0f));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragFloat4(lua_State* L){
	float v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::DragFloat4(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optfloat(L,5,0.0f),luaL_optstring(L,6,"%.3f"),luaL_optfloat(L,7,1.0f));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragFloatRange2(lua_State* L){
	float min,max;
	getbyref(L,2,min);getbyref(L,3,max);
	bool r = ImGui::DragFloatRange2(luaL_checkstring(L,1),&min,&max,luaL_optfloat(L,4,0.0f),
		luaL_optfloat(L,5,0.0f),luaL_optfloat(L,6,0.0f),luaL_optstring(L,7,"%.3f"),
		luaL_optstring(L,8,NULL),(ImGuiSliderFlags)luaL_optfloat(L,9,1.0f));
	setbyref(L,2,min);setbyref(L,3,max);
	lua_pushboolean(L,r);
	return 1;
}

static int DragInt(lua_State* L){
	int v;
	getbyref(L,2,v);
	bool r = ImGui::DragInt(luaL_checkstring(L,1), &v, luaL_optfloat(L,3,1.0f),luaL_optint(L,4,0),
		luaL_optint(L,5,0),luaL_optstring(L,6,"%d"));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragInt2(lua_State* L){
	int v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::DragInt2(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optint(L,4,0),
		luaL_optint(L,5,0),luaL_optstring(L,6,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragInt3(lua_State* L){
	int v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::DragInt3(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optint(L,4,0),
		luaL_optint(L,5,0),luaL_optstring(L,6,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragInt4(lua_State* L){
	int v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::DragInt4(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optint(L,4,0),
		luaL_optint(L,5,0),luaL_optstring(L,6,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int DragIntRange2(lua_State* L){
	int min,max;
	getbyref(L,2,min);getbyref(L,3,max);
	bool r = ImGui::DragIntRange2(luaL_checkstring(L,1),&min,&max,
		luaL_optfloat(L,4,1.0f),
		luaL_optint(L,5,0),luaL_optint(L,6,0),
		luaL_optstring(L,7,"%d"),
		luaL_optstring(L,8,NULL));
	setbyref(L,2,min);setbyref(L,3,max);
	lua_pushboolean(L,r);
	return 1;
}
//TODO
static int DragScalar(lua_State* L){
	//bool r = ImGui::DragScalar(luaL_checkstring(L,1),);
    return 0;
}

static int DragScalarN(lua_State* L) {
	//bool r = ImGui::DragScalar(luaL_checkstring(L,1),);
	return 0;
}
//==========================================================================
// Widgets: Sliders
static int SliderFloat(lua_State* L){
	float v ;
	getbyref(L,2,v);
	bool r = ImGui::SliderFloat(luaL_checkstring(L,1), &v, luaL_checkfloat(L,3), luaL_checkfloat(L,4),
		luaL_optstring(L,5,"%.3f"),luaL_optfloat(L,6,1.0f));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
    return 1;
}

static int SliderFloat2(lua_State* L){
	float v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderFloat2(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optstring(L,5,"%.3f"),luaL_optfloat(L,6,1.0f));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderFloat3(lua_State* L){
	float v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderFloat3(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optstring(L,5,"%.3f"),luaL_optfloat(L,6,1.0f));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderFloat4(lua_State* L){
	float v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderFloat4(luaL_checkstring(L,1),v,luaL_optfloat(L,3,1.0f),luaL_optfloat(L,4,0.0f),
		luaL_optstring(L,5,"%.3f"),luaL_optfloat(L,6,1.0f));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderAngle(lua_State* L){
	float v;
	getbyref(L,2,v);
	bool r = ImGui::SliderAngle(luaL_checkstring(L,1),&v,luaL_optfloat(L,3,-360.0f),luaL_optfloat(L,4,+360.0f),
		luaL_optstring(L,5,"%.0f deg"));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderInt(lua_State* L){
	int v ;
	getbyref(L,2,v);
	bool r = ImGui::SliderInt(luaL_checkstring(L,1), &v, luaL_checkint(L,3), luaL_checkint(L,4),
		luaL_optstring(L,5,"%d"));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderInt2(lua_State* L){
	int v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderInt2(luaL_checkstring(L,1),v,luaL_checkint(L,3),luaL_checkint(L,4),
		luaL_optstring(L,5,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderInt3(lua_State* L){
	int v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderInt3(luaL_checkstring(L,1),v,luaL_checkint(L,3),luaL_checkint(L,4),
		luaL_optstring(L,5,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderInt4(lua_State* L){
	int v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::SliderInt4(luaL_checkstring(L,1),v,luaL_checkint(L,3),luaL_checkint(L,4),
		luaL_optstring(L,5,"%d"));
	setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int SliderScalar(lua_State* L){
	double v;
	double min = luaL_checkfloat(L,3);
	double max = luaL_checkfloat(L,4);
	getbyref(L,2,v);
	bool r = ImGui::SliderScalar(luaL_checkstring(L,1), ImGuiDataType_Double, &v, &min, &max,luaL_optstring(L,5,"%d"),luaL_optfloat(L,6,1.0f));
	setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}
//TODO SliderScalarN
static int VSliderFloat(lua_State* L){
	float v;
	ImVec2 size;
	getbyref(L,3,v);
	gettableVec2(L,2,size);
	bool r = ImGui::VSliderFloat(luaL_checkstring(L,1),size ,&v,luaL_checkfloat(L,4),luaL_checkfloat(L,5),luaL_optstring(L,6,"%.3f"),(ImGuiSliderFlags)luaL_optfloat(L,7,1.0f));
	setbyref(L,3,v);
	lua_pushboolean(L,r);
	return 1;
    return 0;
}

static int VSliderInt(lua_State* L){
	int v;
	ImVec2 size;
	getbyref(L,3,v);
	gettableVec2(L,2,size);
	bool r = ImGui::VSliderInt(luaL_checkstring(L,1),size ,&v,luaL_checkint(L,4),luaL_checkint(L,5),luaL_optstring(L,6,"%d"));
	setbyref(L,3,v);
	lua_pushboolean(L,r);
    return 1;
}
//TODO
static int VSliderScalar(lua_State* L){

    return 0;
}
//==========================================================================
// Widgets: Input with Keyboard

static int InputText(lua_State* L){//
	char *buf;
	size_t buf_size;
	getinputbuf(L,2,buf,buf_size);
	bool r = ImGui::InputText(luaL_checkstring(L,1),buf, buf_size);
	if (r)
		setinputbuf(L,2,buf);
	lua_pushboolean(L,r);
    return 1;
}

static int InputTextMultiline(lua_State* L){
	ImVec2 size(0,0);
	char *buf ;
	size_t buf_size;
	getinputbuf(L,2,buf,buf_size);
	getImVec2(L,3,size);
	bool r = ImGui::InputTextMultiline(luaL_checkstring(L,1),buf,buf_size,size,luaL_optint(L,5,0));
	if (r)
		setinputbuf(L,2,buf);
	lua_pushboolean(L,r);
	return 1;
}

static int InputTextWithHint(lua_State* L){
	char *buf;
	size_t buf_size;
	getinputbuf(L,3,buf,buf_size);
	bool r = ImGui::InputTextWithHint(luaL_checkstring(L,1),luaL_checkstring(L,2),buf, buf_size,luaL_optint(L,4,0));
	if (r)
		setinputbuf(L,3,buf);
	lua_pushboolean(L,r);
	return 1;
}

static int InputFloat(lua_State* L){
	float v;
	getbyref(L,2,v);
	bool r = ImGui::InputFloat(luaL_checkstring(L,1), &v, luaL_checkfloat(L,3),luaL_optfloat(L,4,0.0f),
		luaL_optstring(L,5,"%.3f"),luaL_optint(L,6,0));
	if (r)
		setbyref(L,2,v);
	lua_pushboolean(L,r);
    return 1;
}

static int InputFloat2(lua_State* L){
	float v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::InputFloat2(luaL_checkstring(L,1), v,luaL_optstring(L,3,"%.3f"),luaL_optint(L,4,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputFloat3(lua_State* L){
	float v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::InputFloat3(luaL_checkstring(L,1), v,luaL_optstring(L,3,"%.3f"),luaL_optint(L,4,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputFloat4(lua_State* L){
	float v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::InputFloat4(luaL_checkstring(L,1), v,luaL_optstring(L,3,"%.3f"),luaL_optint(L,4,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputInt(lua_State* L){
	int v ;
	getbyref(L,2,v);
	bool r = ImGui::InputInt(luaL_checkstring(L,1), &v, luaL_optint(L,3,0),luaL_optint(L,4,100),
		luaL_optint(L,5,0));
	if (r)
		setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputInt2(lua_State* L){
	int v[2];
	getbyreftable(L,2,v);
	bool r = ImGui::InputInt2(luaL_checkstring(L,1), v,luaL_optint(L,3,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputInt3(lua_State* L){
	int v[3];
	getbyreftable(L,2,v);
	bool r = ImGui::InputInt3(luaL_checkstring(L,1), v,luaL_optint(L,3,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputInt4(lua_State* L){
	int v[4];
	getbyreftable(L,2,v);
	bool r = ImGui::InputInt4(luaL_checkstring(L,1), v,luaL_optint(L,3,0));
	if (r)
		setbyreftable(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int InputDouble(lua_State* L){
	double v;
	getbyref(L,2,v);
	bool r = ImGui::InputDouble(luaL_checkstring(L,1), &v, luaL_checknumber(L,3),luaL_optnumber(L,4,0.0f),
		luaL_optstring(L,5,"%.6f"),luaL_optint(L,6,0));
	if (r)
		setbyref(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}
//TODO
static int InputScalar(lua_State* L){
	//ImGui::InputScalar();
    return 0;
}
//TODO InputScalarN
//==========================================================================
// Widgets: Color Editor/Picker
static int ColorEdit3(lua_State* L){
	ImVec4 v(0,0,0,0);
	gettableVec4(L,2,v);
	bool r = ImGui::ColorEdit3(luaL_checkstring(L,1), (float*)&v);
	settableVec4(L,2,v);
	lua_pushboolean(L,r);
    return 1;
}

static int ColorEdit4(lua_State* L){
	ImVec4 v(0,0,0,0);
	gettableVec4(L,2,v);
	bool r = ImGui::ColorEdit4(luaL_checkstring(L,1), (float*)&v);
	settableVec4(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int ColorPicker3(lua_State* L){
	ImVec4 v(0,0,0,0);
	gettableVec4(L,2,v);
	bool r = ImGui::ColorPicker3(luaL_checkstring(L,1), (float*)&v);
	settableVec4(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int ColorPicker4(lua_State* L){
	ImVec4 v(0,0,0,0);
	gettableVec4(L,2,v);
	bool r = ImGui::ColorPicker4(luaL_checkstring(L,1), (float*)&v);
	settableVec4(L,2,v);
	lua_pushboolean(L,r);
	return 1;
}

static int ColorButton(lua_State* L){
	ImVec4 v(0,0,0,0);
	ImVec2 size(0,0);
	gettableVec4(L,2,v);
	gettableVec2(L,4,size);
	bool r = ImGui::ColorButton(luaL_checkstring(L,1),v,luaL_optint(L,3,0),size);
	settableVec4(L,2,v);
	settableVec2(L,4,size);
	lua_pushboolean(L,r);
	return 1;
}

static int SetColorEditOptions(lua_State* L){
	ImGui::SetColorEditOptions(luaL_checkint(L,1));
    return 0;
}
//==========================================================================
// Widgets: Trees
static int TreeNode(lua_State* L){
	lua_pushboolean(L,ImGui::TreeNode(luaL_checkstring(L,1)));
    return 1;
}

static int TreeNodeEx(lua_State* L){
	lua_pushboolean(L,ImGui::TreeNodeEx(luaL_checkstring(L,1),luaL_optint(L,2,0)));
    return 1;
}

static int TreePush(lua_State* L){
	ImGui::TreePush(luaL_checkstring(L,1));
    return 0;
}

static int TreePop(lua_State* L){
	ImGui::TreePop();
    return 0;
}

static int GetTreeNodeToLabelSpacing(lua_State* L){
	lua_pushnumber(L,ImGui::GetTreeNodeToLabelSpacing());
    return 1;
}

static int CollapsingHeader(lua_State* L){
	if (lua_istable(L,2)){
		bool v;
		getbyref(L,2,v);
		lua_pushboolean(L,ImGui::CollapsingHeader(luaL_checkstring(L,1),&v,luaL_optint(L,3,0)));
		setbyref(L,2,v);
	}else
		lua_pushboolean(L,ImGui::CollapsingHeader(luaL_checkstring(L,1),luaL_optint(L,2,0)));
    return 1;
}

static int SetNextItemOpen(lua_State* L){
	ImGui::SetNextItemOpen(luaL_checkboolean(L,1),luaL_optint(L,2,0));
    return 0;
}
//==========================================================================
// Widgets: Selectables
static int Selectable(lua_State* L){//
	bool r;
	ImVec2 size(0,0);
	getImVec2(L,4,size);
	if (lua_istable(L,2)){
		bool v;
		getbyref(L,2,v);
		r = ImGui::Selectable(luaL_checkstring(L,1),&v,luaL_optint(L,3,0),size);
		setbyref(L,2,v);
	}else
		r = ImGui::Selectable(luaL_checkstring(L,1),luaL_optboolean(L,2,false),luaL_optint(L,3,0),size);
	lua_pushboolean(L,r);
    return 1;
}
//==========================================================================
// Widgets: List Boxes
static int ListBox(lua_State* L){
	int v;
	getbyref(L,2,v);--v;
	tabledata data(L,3);
	bool r = ImGui::ListBox(luaL_checkstring(L,1),&v,items_getter,&data,(int)luaL_len(L,3),luaL_optint(L,4,-1));
	setbyref(L,2,++v);
	lua_pushboolean(L,r);
    return 1;
}

static int ListBoxHeader(lua_State* L){
	bool r;
	if (lua_istable(L,2)){
		ImVec2 size(0,0);
		gettableVec2(L,2,size);
		r = ImGui::ListBoxHeader(luaL_checkstring(L,1),size);
	}else{
		r = ImGui::ListBoxHeader(luaL_checkstring(L,1),luaL_checkint(L,2),luaL_optint(L,3,-1));
	}
	lua_pushboolean(L,r);
    return 1;
}

static int ListBoxFooter(lua_State* L){
	ImGui::ListBoxFooter();
    return 0;
}
//==========================================================================
// Widgets: Data Plotting

static int PlotLines(lua_State* L){
	tabledata data(L,2);
	ImVec2 size(0,0);
	gettableVec2(L,7,size);
	ImGui::PlotLines(luaL_checkstring(L,1),values_getter,&data,(int)luaL_len(L,2),luaL_optint(L,3,0),
		luaL_optstring(L,4,NULL),luaL_optfloat(L,5,FLT_MAX),luaL_optfloat(L,6,FLT_MAX),size);
    return 0;
}

static int PlotHistogram(lua_State* L){
	tabledata data(L,2);
	ImVec2 size(0,0);
	gettableVec2(L,7,size);
	ImGui::PlotHistogram(luaL_checkstring(L,1),values_getter,&data,(int)luaL_len(L,2),luaL_optint(L,3,0),
		luaL_optstring(L,4,NULL),luaL_optfloat(L,5,FLT_MAX),luaL_optfloat(L,6,FLT_MAX),size);
	return 0;
}
//==========================================================================
// Widgets: Value() Helpers.
static int Value(lua_State* L){
	ImGui::TextUnformatted(lua_tostring(L,1));
    return 0;
}
//==========================================================================
// Widgets: Menus
static int BeginMenuBar(lua_State* L){//
	lua_pushboolean(L,ImGui::BeginMenuBar());
    return 1;
}

static int EndMenuBar(lua_State* L){//
	ImGui::EndMenuBar();
    return 0;
}

static int BeginMainMenuBar(lua_State* L){//
	lua_pushboolean(L,ImGui::BeginMainMenuBar());
    return 1;
}

static int EndMainMenuBar(lua_State* L){//
	ImGui::EndMainMenuBar();
    return 0;
}

static int BeginMenu(lua_State* L){//
	lua_pushboolean(L,ImGui::BeginMenu(luaL_checkstring(L,1),luaL_optboolean(L,2,true)));
	return 1;
}

static int EndMenu(lua_State* L){//
	ImGui::EndMenu();
    return 0;
}

static int MenuItem(lua_State* L){//
	bool r;
	if(lua_istable(L,3)){
		bool v;
		getbyref(L,3,v);
		r = ImGui::MenuItem(luaL_checkstring(L,1),luaL_optstring(L,2,NULL),&v,luaL_optboolean(L,4,true));
		setbyref(L,3,v);
	}else
		r = ImGui::MenuItem(luaL_checkstring(L,1),luaL_optstring(L,2,NULL),luaL_optboolean(L,3,false),luaL_optboolean(L,4,true));

	lua_pushboolean(L,r);
	return 1;
}
//==========================================================================
// Tooltips
static int BeginTooltip(lua_State* L){//
	ImGui::BeginTooltip();
    return 0;
}

static int EndTooltip(lua_State* L){//
	ImGui::EndTooltip();
    return 0;
}

static int SetTooltip(lua_State* L){//
	ImGui::SetTooltip(luaL_checkstring(L,1));
    return 0;
}
//==========================================================================
// Popups, Modals

static int BeginPopup(lua_State* L){
	lua_pushboolean(L,ImGui::BeginPopup(luaL_checkstring(L,1),luaL_optint(L,2,0)));
    return 1;
}

static int BeginPopupModal(lua_State* L) {//
	bool r;
	if (lua_istable(L, 2)) {
		bool v;
		getbyref(L, 2, v);
		r = ImGui::BeginPopupModal(luaL_checkstring(L, 1), &v, luaL_optint(L, 3, 0));
		setbyref(L, 2, v);
	}
	else
		r = ImGui::BeginPopupModal(luaL_checkstring(L, 1), NULL, luaL_optint(L, 2, 0));

	lua_pushboolean(L, r);
	return 1;
}

static int EndPopup(lua_State* L) {//
	ImGui::EndPopup();
	return 0;
}

static int OpenPopup(lua_State* L) {//
	ImGui::OpenPopup(luaL_checkstring(L, 1));
	return 0;
}

static int OpenPopupOnItemClick(lua_State* L) {//
	ImGui::OpenPopupOnItemClick(luaL_optstring(L, 1, NULL), luaL_optint(L, 2, 1));
	return 0;
}

static int CloseCurrentPopup(lua_State* L) {//
	ImGui::CloseCurrentPopup();
	return 0;
}

static int BeginPopupContextItem(lua_State* L){//
	bool r = ImGui::BeginPopupContextItem(luaL_optstring(L,1,NULL),luaL_optint(L,2,1));
	lua_pushboolean(L,r);
    return 1;
}

static int BeginPopupContextWindow(lua_State* L){//
	bool r = ImGui::BeginPopupContextWindow(luaL_optstring(L,1,NULL),luaL_optint(L,2,1),luaL_optboolean(L,3,true));
	lua_pushboolean(L,r);
    return 1;
}

static int BeginPopupContextVoid(lua_State* L){//
	bool r = ImGui::BeginPopupContextVoid(luaL_optstring(L,1,NULL),luaL_optint(L,2,1));
	lua_pushboolean(L,r);
	return 1;
}

static int IsPopupOpen(lua_State* L){//
	bool r = ImGui::IsPopupOpen(luaL_checkstring(L,1));
	lua_pushboolean(L,r);
	return 1;
}
//==========================================================================
// Tables
//TODO BeginTable
//==========================================================================
// Columns
static int Columns(lua_State* L){//
	ImGui::Columns(luaL_optint(L,1,1), luaL_optstring(L,2,NULL), luaL_optboolean(L,3,true));
    return 0;
}

static int NextColumn(lua_State* L){//
	ImGui::NextColumn();
    return 0;
}

static int GetColumnIndex(lua_State* L){//
    lua_pushinteger(L,ImGui::GetColumnIndex());
    return 1;
}

static int GetColumnWidth(lua_State* L){//
    lua_pushnumber(L,ImGui::GetColumnWidth(luaL_optint(L,1,-1)));
    return 1;
}

static int SetColumnWidth(lua_State* L){//
    ImGui::SetColumnWidth(luaL_checkint(L,1),luaL_checkfloat(L,2));
    return 0;
}

static int GetColumnOffset(lua_State* L){//
    lua_pushnumber(L,ImGui::GetColumnOffset(luaL_optint(L,1,-1)));
    return 0;
}

static int SetColumnOffset(lua_State* L){//
    ImGui::SetColumnOffset(luaL_checkint(L,1),luaL_checkfloat(L,2));
    return 0;
}

static int GetColumnsCount(lua_State* L){//
    lua_pushinteger(L,ImGui::GetColumnsCount());
    return 1;
}
//==========================================================================
// Tab Bars, Tabs
static int BeginTabBar(lua_State* L){//
    bool r = ImGui::BeginTabBar(luaL_checkstring(L,1),luaL_optint(L,2,ImGuiTabBarFlags_None));
	lua_pushboolean(L,r);
    return 1;
}

static int EndTabBar(lua_State* L){//
    ImGui::EndTabBar();
    return 0;
}

static int BeginTabItem(lua_State* L){//
	bool r ;
	if (lua_istable(L,2)){
		bool v;
		getbyref(L,2,v);
		r = ImGui::BeginTabItem(luaL_checkstring(L,1),&v,luaL_optint(L,3,ImGuiTabItemFlags_None));
		setbyref(L,2,v);
	}else
		r = ImGui::BeginTabItem(luaL_checkstring(L,1),NULL,luaL_optint(L,2,ImGuiTabItemFlags_None));
	lua_pushboolean(L,r);
    return 1;
}

static int EndTabItem(lua_State* L){//
    ImGui::EndTabItem();
    return 0;
}
//TODO TabItemButton
static int SetTabItemClosed(lua_State* L){//
    ImGui::SetTabItemClosed(luaL_checkstring(L,1));
    return 0;
}
//==========================================================================
// Logging/Capture
static int LogToTTY(lua_State* L){
    ImGui::LogToTTY(luaL_optint(L,1,-1));
    return 0;
}

static int LogToFile(lua_State* L){
    ImGui::LogToFile(luaL_optint(L,1,-1),luaL_optstring(L,2,NULL));
    return 0;
}

static int LogToClipboard(lua_State* L){
    ImGui::LogToClipboard(luaL_optint(L,1,-1));
    return 0;
}

static int LogFinish(lua_State* L){
    ImGui::LogFinish();
    return 0;
}

static int LogButtons(lua_State* L){
    ImGui::LogButtons();
    return 0;
}

static int LogText(lua_State* L){
    ImGui::LogText(luaL_checkstring(L,1));
    return 0;
}
//==========================================================================
// Drag and Drop
static int BeginDragDropSource(lua_State* L){
    lua_pushboolean(L,ImGui::BeginDragDropSource(luaL_optint(L,1,0)));
    return 1;
}

static int SetDragDropPayload(lua_State* L){
    bool r = ImGui::SetDragDropPayload(luaL_checkstring(L,1),luaL_checkstring(L,2),luaL_len(L,2),luaL_optint(L,3,0));
	lua_pushboolean(L,r);
    return 1;
}

static int EndDragDropSource(lua_State* L){
    ImGui::EndDragDropSource();
    return 0;
}

static int BeginDragDropTarget(lua_State* L){
    lua_pushboolean(L,ImGui::BeginDragDropTarget());
    return 1;
}

static int AcceptDragDropPayload(lua_State* L){
    const ImGuiPayload* v = ImGui::AcceptDragDropPayload(luaL_checkstring(L,1),luaL_optint(L,2,0));
	lua_createtable(L,0,7);
	lua_pushlstring(L,(char*)v->Data,v->DataSize);
	lua_setfield(L,-2,"Data");
	lua_pushinteger(L,v->SourceId);
	lua_setfield(L,-2,"SourceId");
	lua_pushinteger(L,v->SourceParentId);
	lua_setfield(L,-2,"SourceParentId");
	lua_pushinteger(L,v->DataFrameCount);
	lua_setfield(L,-2,"DataFrameCount");
	lua_pushlstring(L,v->DataType,32);
	lua_setfield(L,-2,"DataType");
	lua_pushboolean(L,v->Preview);
	lua_setfield(L,-2,"Preview");
	lua_pushboolean(L,v->Delivery);
	lua_setfield(L,-2,"Delivery");
    return 1;
}

static int EndDragDropTarget(lua_State* L){
    ImGui::EndDragDropTarget();
    return 0;
}

static int GetDragDropPayload(lua_State* L){
    const ImGuiPayload* v = ImGui::GetDragDropPayload();
	lua_createtable(L,0,7);
	lua_pushlstring(L,(char*)v->Data,v->DataSize);
	lua_setfield(L,-2,"Data");
	lua_pushinteger(L,v->SourceId);
	lua_setfield(L,-2,"SourceId");
	lua_pushinteger(L,v->SourceParentId);
	lua_setfield(L,-2,"SourceParentId");
	lua_pushinteger(L,v->DataFrameCount);
	lua_setfield(L,-2,"DataFrameCount");
	lua_pushlstring(L,v->DataType,32);
	lua_setfield(L,-2,"DataType");
	lua_pushboolean(L,v->Preview);
	lua_setfield(L,-2,"Preview");
	lua_pushboolean(L,v->Delivery);
	lua_setfield(L,-2,"Delivery");
	return 1;
}
//==========================================================================
// Clipping
static int PushClipRect(lua_State* L){
	ImVec2 min,max;
	gettableVec2(L,1,min);
	gettableVec2(L,2,max);
    ImGui::PushClipRect(min,max,luaL_checkboolean(L,3));
	settableVec2(L,1,min);
	settableVec2(L,2,max);
    return 0;
}

static int PopClipRect(lua_State* L){
    ImGui::PopClipRect();
    return 0;
}
// Focus, Activation
static int SetItemDefaultFocus(lua_State* L){
    ImGui::SetItemDefaultFocus();
    return 0;
}
static int SetKeyboardFocusHere(lua_State* L){
    ImGui::SetKeyboardFocusHere(luaL_optint(L,1,0));
    return 0;
}
//==========================================================================
// Item/Widgets Utilities
static int IsItemHovered(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemHovered(luaL_optint(L,1,ImGuiHoveredFlags_None)));
    return 1;
}

static int IsItemActive(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemActive());
	return 1;
}

static int IsItemFocused(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemFocused());
	return 1;
}

static int IsItemClicked(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemClicked(luaL_optint(L,1,0)));
    return 1;
}

static int IsItemVisible(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemVisible());
	return 1;
}

static int IsItemEdited(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemEdited());
	return 1;
}

static int IsItemActivated(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemActivated());
	return 1;
}

static int IsItemDeactivated(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemDeactivated());
	return 1;
}

static int IsItemDeactivatedAfterEdit(lua_State* L){
	lua_pushboolean(L,ImGui::IsItemDeactivatedAfterEdit());
	return 1;
}

static int IsItemToggledOpen(lua_State* L){//
	lua_pushboolean(L,ImGui::IsItemToggledOpen());
	return 1;
}

static int IsAnyItemHovered(lua_State* L){//
	lua_pushboolean(L,ImGui::IsAnyItemHovered());
	return 1;
}

static int IsAnyItemActive(lua_State* L){//
	lua_pushboolean(L,ImGui::IsAnyItemActive());
	return 1;
}

static int IsAnyItemFocused(lua_State* L){//
	lua_pushboolean(L,ImGui::IsAnyItemFocused());
	return 1;
}

static int GetItemRectMin(lua_State* L){//
	ImVec2 v = ImGui::GetItemRectMin();
	pushImVec2(L,v);
    return 2;
}

static int GetItemRectMax(lua_State* L){//
	ImVec2 v = ImGui::GetItemRectMax();
	pushImVec2(L,v);
	return 2;
}

static int GetItemRectSize(lua_State* L){//
	ImVec2 v = ImGui::GetItemRectSize();
	pushImVec2(L,v);
	return 2;
}

static int SetItemAllowOverlap(lua_State* L){//
	ImGui::SetItemAllowOverlap();
    return 0;
}
//==========================================================================
// Miscellaneous Utilities
static int IsRectVisible(lua_State* L){
	if (lua_istable(L,2)){
		ImVec2 min,max;
		gettableVec2(L,1,min);
		gettableVec2(L,2,max);
		lua_pushboolean(L,ImGui::IsRectVisible(min,max));
	}else{
		ImVec2 v;
		gettableVec2(L,1,v);
		lua_pushboolean(L,ImGui::IsRectVisible(v));
	}
    return 1;
}

static int GetTime(lua_State* L){
	lua_pushnumber(L,ImGui::GetTime());
	return 1;
}

static int GetFrameCount(lua_State* L){
    lua_pushinteger(L,ImGui::GetFrameCount());
    return 1;
}
//TODO
static int GetBackgroundDrawList(lua_State* L){
    //ImGui::GetBackgroundDrawList();
    return 0;
}
//TODO
static int GetForegroundDrawList(lua_State* L){
    //ImGui::GetForegroundDrawList();
    return 0;
}
//TODO
static int GetDrawListSharedData(lua_State* L){
    //ImGui::GetDrawListSharedData();
    return 0;
}
//TODO
static int GetStyleColorName(lua_State* L){
    lua_pushstring(L,ImGui::GetStyleColorName(luaL_checkint(L,1)));
    return 1;
}
//TODO
static int SetStateStorage(lua_State* L){
    //ImGui::SetStateStorage();
    return 0;
}
//TODO
static int GetStateStorage(lua_State* L){
    //ImGui::GetStateStorage();
    return 0;
}

//TODO
static int CalcListClipping(lua_State* L){
    //ImGui::CalcListClipping();
    return 0;
}

static int BeginChildFrame(lua_State* L){
	ImVec2 v;
	gettableVec2(L,2,v);
    bool r = ImGui::BeginChildFrame(luaL_checkint(L,1),v,luaL_optint(L,3,0));
	lua_pushboolean(L,r);
    return 1;
}

static int EndChildFrame(lua_State* L){
    ImGui::EndChildFrame();
    return 0;
}
// Text Utilities
static int CalcTextSize(lua_State* L) {
	ImVec2 v = ImGui::CalcTextSize(luaL_checkstring(L, 1), NULL, luaL_optboolean(L, 2, false), luaL_optfloat(L, 3, -1.0f));
	pushImVec2(L, v);
	return 2;
}
//==========================================================================
// Color Utilities
//TODO
static int ColorConvertU32ToFloat4(lua_State* L){
    //ImGui::ColorConvertU32ToFloat4();
    return 0;
}
//TODO
static int ColorConvertFloat4ToU32(lua_State* L){
    //ImGui::ColorConvertFloat4ToU32();
    return 0;
}
//TODO
static int ColorConvertRGBtoHSV(lua_State* L){
    //ImGui::ColorConvertRGBtoHSV();
    return 0;
}
//TODO
static int ColorConvertHSVtoRGB(lua_State* L){
    //ImGui::ColorConvertHSVtoRGB();
    return 0;
}
//==========================================================================
	// Inputs Utilities: Keyboard
static int GetKeyIndex(lua_State* L){
	lua_pushinteger(L,ImGui::GetKeyIndex(luaL_checkint(L,1)));
    return 1;
}

static int IsKeyDown(lua_State* L){
	lua_pushboolean(L,ImGui::IsKeyDown(luaL_checkint(L,1)));
    return 1;
}

static int IsKeyPressed(lua_State* L){
	lua_pushboolean(L,ImGui::IsKeyPressed(luaL_checkint(L,1),luaL_optboolean(L,2,true)));
    return 1;
}

static int IsKeyReleased(lua_State* L){
	lua_pushboolean(L,ImGui::IsKeyReleased(luaL_checkint(L,1)));
    return 1;
}

static int GetKeyPressedAmount(lua_State* L){
	lua_pushinteger(L,ImGui::GetKeyPressedAmount(luaL_checkint(L,1),luaL_checkfloat(L,2),luaL_checkfloat(L,3)));
    return 1;
}

static int CaptureKeyboardFromApp(lua_State* L) {//
	ImGui::CaptureKeyboardFromApp(luaL_optboolean(L, 1, true));
	return 0;
}

// Inputs Utilities: Mouse
static int IsMouseDown(lua_State* L){//
	lua_pushboolean(L,ImGui::IsMouseDown(luaL_checkint(L,1)));
    return 1;
}

static int IsMouseClicked(lua_State* L) {//
	lua_pushboolean(L, ImGui::IsMouseClicked(luaL_checkint(L, 1), luaL_optboolean(L, 2, false)));
	return 1;
}

static int IsMouseReleased(lua_State* L) {//
	lua_pushboolean(L, ImGui::IsMouseReleased(luaL_checkint(L, 1)));
	return 1;
}

static int IsMouseDoubleClicked(lua_State* L) {//
	lua_pushboolean(L, ImGui::IsMouseDoubleClicked(luaL_checkint(L, 1)));
	return 1;
}

static int IsMouseHoveringRect(lua_State* L) {//
	ImVec2 min, max;
	getImVec2(L, 1, min);
	;	getImVec2(L, 3, max);
	lua_pushboolean(L, ImGui::IsMouseHoveringRect(min, max, luaL_optboolean(L, 5, true)));
	return 1;
}

static int IsMousePosValid(lua_State* L) {//
	if (lua_istable(L, 1)) {
		ImVec2 v(0, 0);
		gettableVec2(L, 1, v);
		lua_pushboolean(L, ImGui::IsMousePosValid(&v));
		settableVec2(L, 1, v);
	}
	else
		lua_pushboolean(L, ImGui::IsMousePosValid(NULL));
	return 0;
}

static int IsAnyMouseDown(lua_State* L) {//
	lua_pushboolean(L, ImGui::IsAnyMouseDown());
	return 1;
}

static int GetMousePos(lua_State* L) {//
	ImVec2 v = ImGui::GetMousePos();
	pushImVec2(L, v);
	return 2;
}

static int GetMousePosOnOpeningCurrentPopup(lua_State* L) {//
	ImVec2 v = ImGui::GetMousePosOnOpeningCurrentPopup();
	pushImVec2(L, v);
	return 2;
}

static int IsMouseDragging(lua_State* L){//
	lua_pushboolean(L,ImGui::IsMouseDragging(luaL_optint(L,1,0),luaL_optfloat(L,2,-0.1f)));
    return 1;
}

static int GetMouseDragDelta(lua_State* L){//
	ImVec2 v = ImGui::GetMouseDragDelta(luaL_optint(L,1,0),luaL_optfloat(L,2,-1.0f));
	pushImVec2(L,v);
	return 2;
}

static int ResetMouseDragDelta(lua_State* L){//
	ImGui::ResetMouseDragDelta(luaL_optint(L,1,0));
    return 0;
}

static int GetMouseCursor(lua_State* L){//
	lua_pushinteger(L,ImGui::GetMouseCursor());
    return 1;
}

static int SetMouseCursor(lua_State* L){//
	ImGui::SetMouseCursor(luaL_checkint(L,1));
    return 0;
}

static int CaptureMouseFromApp(lua_State* L){//
	ImGui::CaptureMouseFromApp(luaL_optboolean(L,1,true));
    return 0;
}
//==========================================================================
// Clipboard Utilities
static int GetClipboardText(lua_State* L){
    lua_pushstring(L,ImGui::GetClipboardText());
    return 1;
}

static int SetClipboardText(lua_State* L){
    ImGui::SetClipboardText(luaL_checkstring(L,1));
    return 0;
}
//==========================================================================
// Settings/.Ini Utilities
static int LoadIniSettingsFromDisk(lua_State* L){
    ImGui::LoadIniSettingsFromDisk(luaL_checkstring(L,1));
    return 0;
}

static int LoadIniSettingsFromMemory(lua_State* L){
    ImGui::LoadIniSettingsFromMemory(luaL_checkstring(L,1),luaL_optint(L,2,0));
    return 0;
}

static int SaveIniSettingsToDisk(lua_State* L){
    ImGui::SaveIniSettingsToDisk(luaL_checkstring(L,1));
    return 0;
}

static int SaveIniSettingsToMemory(lua_State* L){
	size_t size;
	const char* r = ImGui::SaveIniSettingsToMemory(&size);
    lua_pushlstring(L,r,size);
    return 1;
}
// Memory Allocators


int Widgets(lua_State* L){

	luaL_Reg methods[] = {
        {"Begin", Begin},
        {"End", End},
        {"BeginChild", BeginChild},
        {"EndChild", EndChild},
// Windows Utilities
        {"IsWindowAppearing",IsWindowAppearing},
        {"IsWindowCollapsed",IsWindowCollapsed},
        {"IsWindowFocused",IsWindowFocused},
        {"IsWindowHovered",IsWindowHovered},
        {"GetWindowDrawList",GetWindowDrawList},
        {"GetWindowPos",GetWindowPos},
        {"GetWindowSize",GetWindowSize},
        {"GetWindowWidth",GetWindowWidth},
        {"GetWindowHeight",GetWindowHeight},
// Prefer using SetNextXXX
        {"SetNextWindowPos",SetNextWindowPos},
        {"SetNextWindowSize",SetNextWindowSize},
        {"SetNextWindowSizeConstraints",SetNextWindowSizeConstraints},
        {"SetNextWindowContentSize",SetNextWindowContentSize},
        {"SetNextWindowCollapsed",SetNextWindowCollapsed},
        {"SetNextWindowFocus",SetNextWindowFocus},
        {"SetNextWindowBgAlpha",SetNextWindowBgAlpha},
        {"SetWindowPos",SetWindowPos},
        {"SetWindowSize",SetWindowSize},
        {"SetWindowCollapsed",SetWindowCollapsed},
        {"SetWindowFocus",SetWindowFocus},
        {"SetWindowFontScale",SetWindowFontScale},
// Content region
        {"GetContentRegionMax",GetContentRegionMax},
        {"GetContentRegionAvail",GetContentRegionAvail},
        {"GetWindowContentRegionMin",GetWindowContentRegionMin},
        {"GetWindowContentRegionMax",GetWindowContentRegionMax},
        {"GetWindowContentRegionWidth",GetWindowContentRegionWidth},
// Windows Scrolling
        {"GetScrollX",GetScrollX},
        {"GetScrollY",GetScrollY},
        {"GetScrollMaxX",GetScrollMaxX},
        {"GetScrollMaxY",GetScrollMaxY},
        {"SetScrollX",SetScrollX},
        {"SetScrollY",SetScrollY},
        {"SetScrollHereX",SetScrollHereX},
        {"SetScrollHereY",SetScrollHereY},
        {"SetScrollFromPosX",SetScrollFromPosX},
        {"SetScrollFromPosY",SetScrollFromPosY},
// Parameters stacks (shared)
        {"PushFont",PushFont},
        {"PopFont",PopFont},
        {"PushStyleColor",PushStyleColor},
        {"PopStyleColor",PopStyleColor},
        {"PushStyleVar",PushStyleVar},
        {"PopStyleVar",PopStyleVar},
        {"GetStyleColorVec4",GetStyleColorVec4},
        {"GetFont",GetFont},
        {"GetFontSize",GetFontSize},
        {"GetFontTexUvWhitePixel",GetFontTexUvWhitePixel},
        {"GetColorU32",GetColorU32},
// Parameters stacks (current window)
        {"PushItemWidth",PushItemWidth},
        {"PopItemWidth",PopItemWidth},
        {"SetNextItemWidth",SetNextItemWidth},
        {"CalcItemWidth",CalcItemWidth},
        {"PushTextWrapPos",PushTextWrapPos},
        {"PopTextWrapPos",PopTextWrapPos},
        {"PushAllowKeyboardFocus",PushAllowKeyboardFocus},
        {"PopAllowKeyboardFocus",PopAllowKeyboardFocus},
        {"PushButtonRepeat",PushButtonRepeat},
        {"PopButtonRepeat",PopButtonRepeat},
// Cursor / Layout
        {"Separator", Separator},
        {"SameLine", SameLine},
        {"NewLine",NewLine},
        {"Spacing",Spacing},
        {"Dummy",Dummy},
        {"Indent",Indent},
        {"Unindent",Unindent},
        {"BeginGroup",BeginGroup},
        {"EndGroup",EndGroup},
        {"GetCursorPos",GetCursorPos},
        {"GetCursorPosX",GetCursorPosX},
        {"GetCursorPosY",GetCursorPosY},
        {"SetCursorPos",SetCursorPos},
        {"SetCursorPosX",SetCursorPosX},
        {"SetCursorPosY",SetCursorPosY},
        {"GetCursorStartPos",GetCursorStartPos},
        {"GetCursorScreenPos",GetCursorScreenPos},
        {"SetCursorScreenPos",SetCursorScreenPos},
        {"AlignTextToFramePadding",AlignTextToFramePadding},
        {"GetTextLineHeight",GetTextLineHeight},
        {"GetTextLineHeightWithSpacing",GetTextLineHeightWithSpacing},
        {"GetFrameHeight",GetFrameHeight},
        {"GetFrameHeightWithSpacing",GetFrameHeightWithSpacing},
// ID stack/scopes
        {"PushID",PushID},
        {"PopID",PopID},
        {"GetID",GetID},
// Widgets: Text
		{"TextUnformatted",TextUnformatted},
        {"Text",Text},
        {"TextColored",TextColored},
        {"TextDisabled",TextDisabled},
        {"TextWrapped",TextWrapped},
        {"LabelText",LabelText},
        {"BulletText",BulletText},
// Widgets: Main
        {"Button",Button},
        {"SmallButton",SmallButton},
        {"InvisibleButton",InvisibleButton},
        {"ArrowButton",ArrowButton},
        {"Image",Image},
        {"ImageButton",ImageButton},
        {"Checkbox",Checkbox},
        {"CheckboxFlags",CheckboxFlags},
        {"RadioButton",RadioButton},
        {"ProgressBar",ProgressBar},
        {"Bullet",Bullet},
// Widgets: Combo Box
        {"BeginCombo",BeginCombo},
        {"EndCombo",EndCombo},
        {"Combo",Combo},
// Widgets: Drags
        {"DragFloat",DragFloat},
        {"DragFloat2",DragFloat2},
        {"DragFloat3",DragFloat3},
        {"DragFloat4",DragFloat4},
        {"DragFloatRange2",DragFloatRange2},
        {"DragInt",DragInt},
        {"DragInt2",DragInt2},
        {"DragInt3",DragInt3},
        {"DragInt4",DragInt4},
        {"DragIntRange2",DragIntRange2},
        {"DragScalar",DragScalar},
// Widgets: Sliders
        {"SliderFloat", SliderFloat},
        {"SliderFloat2",SliderFloat2},
        {"SliderFloat3",SliderFloat3},
        {"SliderFloat4",SliderFloat4},
        {"SliderAngle",SliderAngle},
        {"SliderInt",SliderInt},
        {"SliderInt2",SliderInt2},
        {"SliderInt3",SliderInt3},
        {"SliderInt4",SliderInt4},
        {"SliderScalar",SliderScalar},
        {"VSliderFloat",VSliderFloat},
        {"VSliderInt",VSliderInt},
        {"VSliderScalar",VSliderScalar},
// Widgets: Input with Keyboard
        {"InputText",InputText},
        {"InputTextMultiline",InputTextMultiline},
        {"InputTextWithHint",InputTextWithHint},
        {"InputFloat",InputFloat},
        {"InputFloat2",InputFloat2},
        {"InputFloat3",InputFloat3},
        {"InputFloat4",InputFloat4},
        {"InputInt",InputInt},
        {"InputInt2",InputInt2},
        {"InputInt3",InputInt3},
        {"InputInt4",InputInt4},
        {"InputDouble",InputDouble},
        {"InputScalar",InputScalar},
// Widgets: Color Editor/Picker
        {"ColorEdit3", ColorEdit3},
        {"ColorEdit4",ColorEdit4},
        {"ColorPicker3",ColorPicker3},
        {"ColorPicker4",ColorPicker4},
        {"ColorButton",ColorButton},
        {"SetColorEditOptions",SetColorEditOptions},
// Widgets: Trees
        {"TreeNode",TreeNode},
        {"TreeNodeEx",TreeNodeEx},
        {"TreePush",TreePush},
        {"TreePop",TreePop},
        {"GetTreeNodeToLabelSpacing",GetTreeNodeToLabelSpacing},
        {"CollapsingHeader",CollapsingHeader},
        {"SetNextItemOpen",SetNextItemOpen},
// Widgets: Selectables
        {"Selectable",Selectable},
// Widgets: List Boxes
        {"ListBox",ListBox},
        {"ListBoxHeader",ListBoxHeader},
        {"ListBoxFooter",ListBoxFooter},
// Widgets: Data Plotting
		{"PlotLines",PlotLines},
		{"PlotHistogram",PlotHistogram},
// Widgets: Value() Helpers.
        {"Value",Value},
// Widgets: Menus
        {"BeginMenuBar",BeginMenuBar},
        {"EndMenuBar",EndMenuBar},
        {"BeginMainMenuBar",BeginMainMenuBar},
        {"EndMainMenuBar",EndMainMenuBar},
        {"BeginMenu",BeginMenu},
        {"EndMenu",EndMenu},
        {"MenuItem",MenuItem},
// Tooltips
        {"BeginTooltip",BeginTooltip},
        {"EndTooltip",EndTooltip},
        {"SetTooltip",SetTooltip},
// Popups, Modals
        {"OpenPopup",OpenPopup},
        {"BeginPopup",BeginPopup},
        {"BeginPopupContextItem",BeginPopupContextItem},
        {"BeginPopupContextWindow",BeginPopupContextWindow},
        {"BeginPopupContextVoid",BeginPopupContextVoid},
        {"BeginPopupModal",BeginPopupModal},
        {"EndPopup",EndPopup},
        {"OpenPopupOnItemClick",OpenPopupOnItemClick},
        {"IsPopupOpen",IsPopupOpen},
        {"CloseCurrentPopup",CloseCurrentPopup},
// Columns
        {"Columns",Columns},
        {"NextColumn",NextColumn},
        {"GetColumnIndex",GetColumnIndex},
        {"GetColumnWidth",GetColumnWidth},
        {"SetColumnWidth",SetColumnWidth},
        {"GetColumnOffset",GetColumnOffset},
        {"SetColumnOffset",SetColumnOffset},
        {"GetColumnsCount",GetColumnsCount},
// Tab Bars, Tabs
        {"BeginTabBar",BeginTabBar},
        {"EndTabBar",EndTabBar},
        {"BeginTabItem",BeginTabItem},
        {"EndTabItem",EndTabItem},
        {"SetTabItemClosed",SetTabItemClosed},
// Logging/Capture
        {"LogToTTY",LogToTTY},
        {"LogToFile",LogToFile},
        {"LogToClipboard",LogToClipboard},
        {"LogFinish",LogFinish},
        {"LogButtons",LogButtons},
        {"LogText",LogText},
// Drag and Drop
        {"BeginDragDropSource",BeginDragDropSource},
        {"SetDragDropPayload",SetDragDropPayload},
        {"EndDragDropSource",EndDragDropSource},
        {"BeginDragDropTarget",BeginDragDropTarget},
        {"AcceptDragDropPayload",AcceptDragDropPayload},
        {"EndDragDropTarget",EndDragDropTarget},
        {"GetDragDropPayload",GetDragDropPayload},
// Clipping
        {"PushClipRect",PushClipRect},
        {"PopClipRect",PopClipRect},
// Focus, Activation
        {"SetItemDefaultFocus",SetItemDefaultFocus},
        {"SetKeyboardFocusHere",SetKeyboardFocusHere},
// Item/Widgets Utilities
        {"IsItemHovered",IsItemHovered},
        {"IsItemActive",IsItemActive},
        {"IsItemFocused",IsItemFocused},
        {"IsItemClicked",IsItemClicked},
        {"IsItemVisible",IsItemVisible},
        {"IsItemEdited",IsItemEdited},
        {"IsItemActivated",IsItemActivated},
        {"IsItemDeactivated",IsItemDeactivated},
        {"IsItemDeactivatedAfterEdit",IsItemDeactivatedAfterEdit},
        {"IsItemToggledOpen",IsItemToggledOpen},
        {"IsAnyItemHovered",IsAnyItemHovered},
        {"IsAnyItemActive",IsAnyItemActive},
        {"IsAnyItemFocused",IsAnyItemFocused},
        {"GetItemRectMin",GetItemRectMin},
        {"GetItemRectMax",GetItemRectMax},
        {"GetItemRectSize",GetItemRectSize},
        {"SetItemAllowOverlap",SetItemAllowOverlap},
// Miscellaneous Utilities
        {"IsRectVisible",IsRectVisible},
        {"GetTime",GetTime},
        {"GetFrameCount",GetFrameCount},
        {"GetBackgroundDrawList",GetBackgroundDrawList},
        {"GetForegroundDrawList",GetForegroundDrawList},
        {"GetDrawListSharedData",GetDrawListSharedData},
        {"GetStyleColorName",GetStyleColorName},
        {"SetStateStorage",SetStateStorage},
        {"GetStateStorage",GetStateStorage},
        {"CalcTextSize",CalcTextSize},
        {"CalcListClipping",CalcListClipping},
        {"BeginChildFrame",BeginChildFrame},
        {"EndChildFrame",EndChildFrame},
// Color Utilities
        {"ColorConvertU32ToFloat4",ColorConvertU32ToFloat4},
        {"ColorConvertFloat4ToU32",ColorConvertFloat4ToU32},
        {"ColorConvertRGBtoHSV",ColorConvertRGBtoHSV},
        {"ColorConvertHSVtoRGB",ColorConvertHSVtoRGB},
// Inputs Utilities
        {"GetKeyIndex",GetKeyIndex},
        {"IsKeyDown",IsKeyDown},
        {"IsKeyPressed",IsKeyPressed},
        {"IsKeyReleased",IsKeyReleased},
        {"GetKeyPressedAmount",GetKeyPressedAmount},
        {"IsMouseDown",IsMouseDown},
        {"IsAnyMouseDown",IsAnyMouseDown},
        {"IsMouseClicked",IsMouseClicked},
        {"IsMouseDoubleClicked",IsMouseDoubleClicked},
        {"IsMouseReleased",IsMouseReleased},
        {"IsMouseDragging",IsMouseDragging},
        {"IsMouseHoveringRect",IsMouseHoveringRect},
        {"IsMousePosValid",IsMousePosValid},
        {"GetMousePos",GetMousePos},
        {"GetMousePosOnOpeningCurrentPopup",GetMousePosOnOpeningCurrentPopup},
        {"GetMouseDragDelta",GetMouseDragDelta},
        {"ResetMouseDragDelta",ResetMouseDragDelta},
        {"GetMouseCursor",GetMouseCursor},
        {"SetMouseCursor",SetMouseCursor},
        {"CaptureKeyboardFromApp",CaptureKeyboardFromApp},
        {"CaptureMouseFromApp",CaptureMouseFromApp},
// Clipboard Utilities
        {"GetClipboardText",GetClipboardText},
        {"SetClipboardText",SetClipboardText},
// Settings/.Ini Utilities
        {"LoadIniSettingsFromDisk",LoadIniSettingsFromDisk},
        {"LoadIniSettingsFromMemory",LoadIniSettingsFromMemory},
        {"SaveIniSettingsToDisk",SaveIniSettingsToDisk},
        {"SaveIniSettingsToMemory",SaveIniSettingsToMemory},
// Memory Allocators

		{NULL, NULL},
	};
	luaL_setfuncs(L,methods,0);
	return 0;
}